#include "stm32f10x_usart.h"
#include "sys.h"
#include "uart.h"
#include "stdio.h"

u8 USART_RX_BUF[USART_REC_LEN];
u16 USART_RX_STA=0;

void uart_init(u32 bound) 
{
	GPIO_InitTypeDef GPIO_InitStructure;
	USART_InitTypeDef USART_InitStructure;
#ifndef IAP
	NVIC_InitTypeDef NVIC_InitStructure;
#endif
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1 | RCC_APB2Periph_GPIOA, ENABLE);

	// USART1_TX   GPIOA.9
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; // PA.9
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; // 复用推挽输出
	GPIO_Init(GPIOA, &GPIO_InitStructure);

	// USART1_RX	  GPIOA.10
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;            // PA10
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; // 浮空输入
	GPIO_Init(GPIOA, &GPIO_InitStructure);

	// Usart1 NVIC
#ifndef IAP
	NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 3; // 抢占优先级
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;        // 子优先级
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;           // IRQ通道使能
	NVIC_Init(&NVIC_InitStructure);
#endif
	// USART1
	USART_InitStructure.USART_BaudRate = bound; // 波特率
	USART_InitStructure.USART_WordLength = USART_WordLength_8b;
	USART_InitStructure.USART_StopBits = USART_StopBits_1;
	USART_InitStructure.USART_Parity = USART_Parity_No;
	USART_InitStructure.USART_HardwareFlowControl =
	USART_HardwareFlowControl_None;
	USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;

	USART_Init(USART1, &USART_InitStructure);
#ifndef IAP
	USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);
#endif
	USART_Cmd(USART1, ENABLE);
}

void USART1_IRQHandler(void) 
{
	u8 Res = 0;
	if (USART_GetITStatus(USART1, USART_IT_RXNE) != RESET) {
		Res = USART_ReceiveData(USART1);

		if ((USART_RX_STA & 0x8000) == 0) {
			if (USART_RX_STA & 0x4000) {
				if (Res != 0x0a)
					USART_RX_STA = 0;
				else
					USART_RX_STA |= 0x8000;
			} else {
				if (Res == 0x0d)
					USART_RX_STA |= 0x4000;
				else {
					USART_RX_BUF[USART_RX_STA & 0X3FFF] = Res;
					USART_RX_STA++;
					if (USART_RX_STA > (USART_REC_LEN - 1))
						USART_RX_STA = 0;
				}
			}
		}
	}
}

#ifdef RTT_DEBUG
#include "stdio.h"
#include "SEGGER_RTT.h"

const char __stdout_name[] = "STDOUT";
const char __stderr_name[] = "STDERR";


int fputc(int ch, FILE *f) {
    SEGGER_RTT_PutChar(0, ch);
    return ch;
}
#else
int fputc(int ch, FILE* f)
{
    while ((USART1->SR & USART_FLAG_TC) == 0) {}
    USART1->DR = (u8)ch;
    return ch;
}
#endif

void SerialPutChar(uint8_t c)
{
	USART_SendData(USART1, c);
	while (USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET)
	{
	}
}

void Serial_PutString(uint8_t *s)
{
	while (*s != '\0')
	{
		SerialPutChar(*s);
		s++;
	}
}
